##### Entry point of autotest for one testcase.
##    It compiles given testcase, and invoke RTL simulator.
##
##    Usage: make test CASE0=<core0_case_file> CASE1=<core1_case_file>
##           make clean
##           make cleanall ; also clean built testcases for RTL sim
##
##    Example: make test CASE0=test_timer/int_start_stop.c
##      Testcase root directory is given by AUTOTESTS below

##### configurable variables
## auto test environment for RTL sim OS, redhat7.9
AUTOENV  ?= ~/autoenv
TOOLHOME := D:/qx/QX-IDE/plugins/QXTOOLS_1.0.0.202411121128/qxtools/toolchain/3slot_320f
PYTHON   := python
OSENV    :=

## path for chip tests
CHIPTEST_ROOT := D:/cygwin64/home/49037/gitlab/dsp_lib/qx_tools/chip_autotest
CHIPTEST_BIN  := $(CHIPTEST_ROOT)/Release/chip_autotest.exe
CHIPTEST_MEM  ?= sram

CASE0      ?=
CASE1      ?=
VCS_DEFINE ?=
TESTCORE   ?= 0

# model compilation option from vcs/Makefile
MODEL_COMP ?=

## env settings
ifneq (,$(findstring linux,$(OSTYPE)))
    TOOLHOME := $(AUTOENV)/toolchain_3slot_320f
    PYTHON   := python3
endif

AUTOTESTS      := libs/autotests

TESTCASE_BIN_TOP := build.auto
TESTCASE_NAME    := $(basename $(notdir $(CASE0)))
TESTCASE_SRC_DIR := $(dir $(CASE0))
TESTCASE_EXPECTS := $(AUTOTESTS)/$(TESTCASE_SRC_DIR)/core0

# update relative directories if testing core1
CLANG_DEFINES :=
ifneq (0,$(TESTCORE))
	TESTCASE_NAME    := $(basename $(notdir $(CASE1)))
	TESTCASE_SRC_DIR := $(dir $(CASE1))
	TESTCASE_EXPECTS := $(AUTOTESTS)/$(TESTCASE_SRC_DIR)/core1
	CLANG_DEFINES    := -DOPEN_CORE1_CLK
endif

TESTCASE_SUBDIR  := $(TESTCASE_SRC_DIR)$(TESTCASE_NAME)
TESTCASE_BIN_DIR := $(TESTCASE_BIN_TOP)/$(TESTCASE_SUBDIR)
TESTCASE_PREFIX  := $(subst /,_,$(TESTCASE_SUBDIR))

## testcase settings
EXP_CORE0_DM   := $(TESTCASE_EXPECTS)/$(TESTCASE_NAME).core0_dm
EXP_CORE0_GR   := $(TESTCASE_EXPECTS)/$(TESTCASE_NAME).core0_gr
EXP_CORE0_PERI := $(TESTCASE_EXPECTS)/$(TESTCASE_NAME).core0_peri
EXP_CORE0_SPRS := $(TESTCASE_EXPECTS)/$(TESTCASE_NAME).core0_sprs
EXP_CORE1_DM   := $(TESTCASE_EXPECTS)/$(TESTCASE_NAME).core1_dm
EXP_CORE1_GR   := $(TESTCASE_EXPECTS)/$(TESTCASE_NAME).core1_gr
EXP_CORE1_PERI := $(TESTCASE_EXPECTS)/$(TESTCASE_NAME).core1_peri
EXP_CORE1_SPRS := $(TESTCASE_EXPECTS)/$(TESTCASE_NAME).core1_sprs

MAKEFILE_AUTO := Makefile.auto

## vcs sim settings
QX_C2000_ROOT ?= ~/qx_c2000
VCS_DIR       := $(QX_C2000_ROOT)/vcs
TESTING_DIR   := $(VCS_DIR)/testfile
EXP_RESULTS_DIR := $(TESTING_DIR)/$(TESTCASE_PREFIX)/simfile
ACT_RESULTS_DIR := $(TESTING_DIR)/$(TESTCASE_PREFIX)/out
PASS_FAIL_FILE  := running.log

## program images files for RTL simulation
FLASH_IMAGE_FILE      := init_mem.txt
CORE0_DRAM_IMAGE_FILE := outer_data_mem_core0.dat
CORE0_IRAM_IMAGE_FILE := outer_insn_mem_core0.dat
CORE1_DRAM_IMAGE_FILE := outer_data_mem_core1.dat
CORE1_IRAM_IMAGE_FILE := outer_insn_mem_core1.dat

##### Build rules
.PHONY: build_case test build_case_deps clean cleanslink cleandeps cleanall build_chipcase

default: test

ifeq ($(CASE0),)
$(info CASE0 not set)
build_case:
build_chipcase:
else ifeq ($(CASE1),)
build_case: BUILD_BOOT BUILD_CORE0 GEN_FLASH_IMG MV_CASE0 TOUCH_CASE1 MV_FLASH_IMG CP_EXPECTED
build_chipcase: BUILD_BOOT BUILD_CHIP_CORE0 GEN_FLASH_IMG MV_CASE0 TOUCH_CASE1 MV_FLASH_IMG CP_CHIP_EXPECTED
build_only_deps: BUILD_BOOT BUILD_CORE0 GEN_FLASH_IMG
else
build_case: BUILD_BOOT BUILD_CORE0 BUILD_CORE1 GEN_FLASH_IMG MV_CASE0 MV_CASE1 MV_FLASH_IMG CP_EXPECTED
build_chipcase: BUILD_BOOT BUILD_CHIP_CORE0 BUILD_CHIP_CORE1 GEN_FLASH_IMG MV_CASE0 MV_CASE1 MV_FLASH_IMG CP_CHIP_EXPECTED
build_only_deps: BUILD_BOOT BUILD_CORE0 BUILD_CORE1 GEN_FLASH_IMG
endif

ifneq (,$(findstring linux,$(OSTYPE)))
OSENV := --linux
build_case_deps: createslink build_case
cleandeps: cleanslink
else
OSENV := 
build_case_deps: build_case
cleandeps: 
endif

COMMON_ARGS := AUTOENV=$(AUTOENV) TOOLHOME=$(TOOLHOME) PYTHON=$(PYTHON) OSENV=$(OSENV) AUTOTESTS=../$(AUTOTESTS)

createslink:
	@ln -sf $(AUTOENV)/lib/ld-linux-x86-64.so.2 bootloader/ld-linux-x86-64.so.2
	@ln -sf $(AUTOENV)/lib/ld-linux-x86-64.so.2 software_lib_driver_core0/ld-linux-x86-64.so.2
	@ln -sf $(AUTOENV)/lib/ld-linux-x86-64.so.2 software_lib_driver_core1/ld-linux-x86-64.so.2

BUILD_BOOT:
	@make -C bootloader -f $(MAKEFILE_AUTO) $(COMMON_ARGS)

BUILD_CORE0:
	@make -C software_lib_driver_core0 -f $(MAKEFILE_AUTO) $(COMMON_ARGS) TESTCASE=$(CASE0) CLANG_DEFINES=$(CLANG_DEFINES)

BUILD_CHIP_CORE0:
	@make -C software_lib_driver_core0 -f $(MAKEFILE_AUTO) $(COMMON_ARGS) TESTCASE=$(CASE0) CLANG_DEFINES="$(CLANG_DEFINES) -DCHIP_AUTOTEST"

BUILD_CORE1:
	@make -C software_lib_driver_core1 -f $(MAKEFILE_AUTO) $(COMMON_ARGS) TESTCASE=$(CASE1) CLANG_DEFINES=$(CLANG_DEFINES)

BUILD_CHIP_CORE1:
	@make -C software_lib_driver_core1 -f $(MAKEFILE_AUTO) $(COMMON_ARGS) TESTCASE=$(CASE1) CLANG_DEFINES="$(CLANG_DEFINES) -DCHIP_AUTOTEST"

GEN_FLASH_IMG:
	$(PYTHON) $(TOOLHOME)/bin/gen_flash_image.py

MV_CASE0:
	@mkdir -p $(TESTCASE_BIN_DIR)
	@mv software_lib_driver_core0/Release/dram_image.core0.dat $(TESTCASE_BIN_DIR)/$(CORE0_DRAM_IMAGE_FILE)
	@mv software_lib_driver_core0/Release/iram_image.core0.dat $(TESTCASE_BIN_DIR)/$(CORE0_IRAM_IMAGE_FILE)
	@mv software_lib_driver_core0/Release/software_lib_driver_core0.dis $(TESTCASE_BIN_DIR)/
	@mv software_lib_driver_core0/Release/linkMapFile $(TESTCASE_BIN_DIR)/linkMapFile_core0

MV_CASE1:
	@mv software_lib_driver_core1/Release/dram_image.core1.dat $(TESTCASE_BIN_DIR)/$(CORE1_DRAM_IMAGE_FILE)
	@mv software_lib_driver_core1/Release/iram_image.core1.dat $(TESTCASE_BIN_DIR)/$(CORE1_IRAM_IMAGE_FILE)
	@mv software_lib_driver_core1/Release/software_lib_driver_core1.dis $(TESTCASE_BIN_DIR)/
	@mv software_lib_driver_core1/Release/linkMapFile $(TESTCASE_BIN_DIR)/linkMapFile_core1

TOUCH_CASE1:
	@touch $(TESTCASE_BIN_DIR)/$(CORE1_DRAM_IMAGE_FILE)
	@touch $(TESTCASE_BIN_DIR)/$(CORE1_IRAM_IMAGE_FILE)

MV_FLASH_IMG:
	@mv flash_image.hex $(TESTCASE_BIN_DIR)/$(FLASH_IMAGE_FILE)

CP_EXPECTED:
	@touch $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core0_dm
	@touch $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core0_gr
	@touch $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core0_peri
	@touch $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core0_sprs
	@touch $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core1_dm
	@touch $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core1_gr
	@touch $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core1_peri
	@touch $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core1_sprs
	@cp $(EXP_CORE0_DM)   $(TESTCASE_BIN_DIR)/ 2>/dev/null || :
	@cp $(EXP_CORE0_GR)   $(TESTCASE_BIN_DIR)/ 2>/dev/null || :
	@cp $(EXP_CORE0_PERI) $(TESTCASE_BIN_DIR)/ 2>/dev/null || :
	@cp $(EXP_CORE0_SPRS) $(TESTCASE_BIN_DIR)/ 2>/dev/null || :
	@cp $(EXP_CORE1_DM)   $(TESTCASE_BIN_DIR)/ 2>/dev/null || :
	@cp $(EXP_CORE1_GR)   $(TESTCASE_BIN_DIR)/ 2>/dev/null || :
	@cp $(EXP_CORE1_PERI) $(TESTCASE_BIN_DIR)/ 2>/dev/null || :
	@cp $(EXP_CORE1_SPRS) $(TESTCASE_BIN_DIR)/ 2>/dev/null || :

CP_CHIP_EXPECTED:
	@cp $(TESTCASE_EXPECTS)/$(TESTCASE_NAME).txt $(TESTCASE_BIN_DIR)/expected_results.txt

setup_run_env:
	@rm -f $(TESTING_DIR)/*.txt
	@rm -rf $(TESTING_DIR)/$(TESTCASE_PREFIX)
	@mkdir -p $(EXP_RESULTS_DIR) $(ACT_RESULTS_DIR)
	@cp $(TESTCASE_BIN_DIR)/$(FLASH_IMAGE_FILE)         $(TESTING_DIR)/$(TESTCASE_PREFIX).txt
	@cp $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core0_dm   $(EXP_RESULTS_DIR)/$(TESTCASE_PREFIX).core0_dm
	@cp $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core0_gr   $(EXP_RESULTS_DIR)/$(TESTCASE_PREFIX).core0_gr
	@cp $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core0_peri $(EXP_RESULTS_DIR)/$(TESTCASE_PREFIX).core0_peri
	@cp $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core0_sprs $(EXP_RESULTS_DIR)/$(TESTCASE_PREFIX).core0_sprs
	@cp $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core1_dm   $(EXP_RESULTS_DIR)/$(TESTCASE_PREFIX).core1_dm
	@cp $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core1_gr   $(EXP_RESULTS_DIR)/$(TESTCASE_PREFIX).core1_gr
	@cp $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core1_peri $(EXP_RESULTS_DIR)/$(TESTCASE_PREFIX).core1_peri
	@cp $(TESTCASE_BIN_DIR)/$(TESTCASE_NAME).core1_sprs $(EXP_RESULTS_DIR)/$(TESTCASE_PREFIX).core1_sprs

build: build_only_deps

runonly:
	@mkdir -p $(TESTCASE_BIN_DIR)/out
	@echo "perl ./test.pl $(MODEL_COMP) $(VCS_DEFINE) pass! $(TESTCASE_PREFIX)" > $(TESTCASE_BIN_DIR)/out/$(PASS_FAIL_FILE)

# echo "perl ./test.pl $(MODEL_COMP) $(VCS_DEFINE) pass! $(TESTCASE_PREFIX)" > $(ACT_RESULTS_DIR)/$(PASS_FAIL_FILE)
test: build_case_deps setup_run_env
	@cd $(VCS_DIR); perl ./test.pl $(MODEL_COMP) $(VCS_DEFINE); cd -
	@cp -r $(ACT_RESULTS_DIR) $(TESTCASE_BIN_DIR)
	@mv $(TESTCASE_BIN_DIR)/out/$(TESTCASE_PREFIX).core0_dm_out   $(TESTCASE_BIN_DIR)/out/$(TESTCASE_NAME).core0_dm   2>/dev/null || :
	@mv $(TESTCASE_BIN_DIR)/out/$(TESTCASE_PREFIX).core0_gr_out   $(TESTCASE_BIN_DIR)/out/$(TESTCASE_NAME).core0_gr   2>/dev/null || :
	@mv $(TESTCASE_BIN_DIR)/out/$(TESTCASE_PREFIX).core0_peri_out $(TESTCASE_BIN_DIR)/out/$(TESTCASE_NAME).core0_peri 2>/dev/null || :
	@mv $(TESTCASE_BIN_DIR)/out/$(TESTCASE_PREFIX).core0_sprs_out $(TESTCASE_BIN_DIR)/out/$(TESTCASE_NAME).core0_sprs 2>/dev/null || :
	@mv $(TESTCASE_BIN_DIR)/out/$(TESTCASE_PREFIX).core1_dm_out   $(TESTCASE_BIN_DIR)/out/$(TESTCASE_NAME).core1_dm   2>/dev/null || :
	@mv $(TESTCASE_BIN_DIR)/out/$(TESTCASE_PREFIX).core1_gr_out   $(TESTCASE_BIN_DIR)/out/$(TESTCASE_NAME).core1_gr   2>/dev/null || :
	@mv $(TESTCASE_BIN_DIR)/out/$(TESTCASE_PREFIX).core1_peri_out $(TESTCASE_BIN_DIR)/out/$(TESTCASE_NAME).core1_peri 2>/dev/null || :
	@mv $(TESTCASE_BIN_DIR)/out/$(TESTCASE_PREFIX).core1_sprs_out $(TESTCASE_BIN_DIR)/out/$(TESTCASE_NAME).core1_sprs 2>/dev/null || :

chiptest: build_chipcase
	@powershell.exe -Command $(CHIPTEST_BIN) --workdir $(TESTCASE_BIN_DIR) --chiptype 049 --memtype $(CHIPTEST_MEM)

cleanslink:
	@rm -f bootloader/ld-linux-x86-64.so.2
	@rm -f software_lib_driver_core0/ld-linux-x86-64.so.2
	@rm -f software_lib_driver_core1/ld-linux-x86-64.so.2

clean: cleandeps
	@make -C bootloader -f $(MAKEFILE_AUTO) clean
	@make -C software_lib_driver_core0 -f $(MAKEFILE_AUTO) clean
	@make -C software_lib_driver_core1 -f $(MAKEFILE_AUTO) clean

cleanall: clean
	rm -rf $(TESTCASE_BIN_TOP) *.hex
